import React from "react";
import {Checkbox} from "antd";
import {Column, ColumnApi, GridApi} from "ag-grid-community";
import _ from "lodash";
import * as mobx from 'mobx'
import Grid from "./grid";
import * as Extend from "../../extend";

interface CheckboxVJsonHeaderProp {
    displayName: string
    api: GridApi
    columnApi: ColumnApi
    column: Column
    reactContainer: HTMLElement
    grid: Grid
}

interface CheckboxVJsonHeaderState {
    checked: boolean
    indeterminate: boolean
}

export default class CheckboxVJsonHeaderRender extends React.Component<CheckboxVJsonHeaderProp, CheckboxVJsonHeaderState> {

    disposer?: () => void

    constructor(props: CheckboxVJsonHeaderProp) {
        super(props);
        this.state = {
            checked: false,
            indeterminate: false
        }
    }

    componentWillMount() {
        this.disposer = mobx.autorun(() => {
            const colDef = this.props.column.getColDef()
            // @ts-ignore
            const {bind, checkboxDisabled} = colDef
            if (!bind) {
                throw new TypeError(`所有 view === 'checkbox' 的列必须指定一个绑定目标 bind=[mobx]`)
            }

            // @ts-ignore
            const grid: Grid = this.props.api.vue
            const scope = grid.props.$context.scopeInstance
            const myState: string[] = _.get(scope, bind)

            // forWatch
            grid.dataVersion.get()
            if (myState.length <= 0) {
                this.setState({
                    indeterminate: false,
                    checked: false
                })

            } else {
                let hasOneChecked = false
                let isAllChecked = true
                try {
                    this.props.api.forEachNode((node) => {

                        if (typeof checkboxDisabled === 'function') {
                            const isDisabled = checkboxDisabled.call(grid, {
                                api: this.props.api,
                                columnApi: this.props.columnApi,
                                column: this.props.column,
                                data: node.data
                            })

                            if (isDisabled) {
                                return
                            }
                        }

                        const id = grid._getIdByRow(node.data)
                        if (_.findIndex(myState, (v) => grid._getIdByRow(v) === id) < 0) {
                            // 只要有一行数据，没有包含在 myState 里，就是没有勾选
                            isAllChecked = false

                        } else {
                            // 有任何一行数据在勾选里，就算半选
                            hasOneChecked = true
                            if (!isAllChecked) {
                                throw Error()
                            }
                        }
                    })
                } catch (e) {
                }

                if (isAllChecked) {
                    this.setState({
                        checked: true,
                        indeterminate: false
                    })
                } else if (hasOneChecked) {
                    this.setState({
                        checked: false,
                        indeterminate: true
                    })
                } else {
                    this.setState({
                        checked: false,
                        indeterminate: false
                    })
                }
            }
        })
    }

    onChange(event: any) {
        const colDef = this.props.column.getColDef()
        // @ts-ignore
        const {bind, checkboxDisabled} = colDef
        if (!bind) {
            throw new TypeError(`所有 view === 'checkbox' 的列必须指定一个绑定目标 bind=[mobx]`)
        }

        // @ts-ignore
        const grid: Grid = this.props.api.vue
        const scope = grid.props.$context.scopeInstance
        const myState: string[] = _.get(scope, bind)
        this.props.grid.checkedRows = myState
        const checked = event.target.checked

        // 根据 isDisabled 状态，获取表格当页里所有的数据
        const rows: string[] = []
        this.props.api.forEachNode((node) => {
            const row = node.data
            if (typeof checkboxDisabled === 'function') {
                const isDisabled = checkboxDisabled.call(grid, {
                    api: this.props.api,
                    columnApi: this.props.columnApi,
                    column: this.props.column,
                    data: node.data
                })

                if (isDisabled) {
                    return
                }
            }
            rows.push(row)
        })

        if (checked) {
            // 全部勾选
            if (!myState) {
                _.set(scope, bind, rows)
            } else {
                mobx.transaction(() => {
                    rows.forEach((row) => {
                        if (_.findIndex(myState, v => grid._getIdByRow(v) === grid._getIdByRow(row)) < 0) {
                            myState.push(row)
                        }
                    })
                })
            }

        } else {
            // 全不选
            mobx.transaction(() => {
                _.remove(myState, (v) => _.findIndex(rows, (v2) => grid._getIdByRow(v) === grid._getIdByRow(v2)) >= 0)
            })
        }
        grid.allCheckedCallBack && grid.allCheckedCallBack(checked)
    }

    componentWillUnmount() {
        if (this.disposer) {
            this.disposer()
        }
    }

    render() {
        if (Extend.isDebugMode()) {
            console.log('CheckboxVJsonHeaderRender', this.props)
        }
        return (
            <Checkbox
                checked={this.state.checked}
                onChange={this.onChange.bind(this)}
                indeterminate={this.state.indeterminate}
            />
        )
    }
}
